﻿using ATEC.GeometryNET;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using ATEC.ATDataCoreNET;
using ATEC.ATDataCoreNET.ATObjects;
using ATEC.ATDataCoreNET.ATCCL;
using SSDPNET.DataCore;
//using SSDPNET.SZEWObject;
using SSDPNET.Geom;
using ATEC.CCLObj.CCFWork;
using SZEWAlignmentNet.AlignmentInterface;

namespace DoModelExample
{
    public class CreateComponentExample
    {
        public static ComponentInfo componentModel = null;
        //当前激活Scene
        public static ATProject masterATProject = null;
        public static ATSceneRef scene = null;
        public static bool isDoModel = false;

        /// <summary>
        /// 建模入口
        /// </summary>
        public static void StartCreateComponent()
        {
            //初始化数据
            componentModel = new ComponentInfo();
            masterATProject = SSDPNET.ATObjFuncs.ProjectObjGetMasterProject();
            scene = SZEWAlignmentInterface.GetSpatialScene(masterATProject);
            isDoModel = false;

            //0. 删除前一次的模型和数据
            ClearDataFromScene();

            //1. 导入CCFWork
            ImportCCFWork();

            //2. 选择路线
            AlignmentSelectionTool.Start("选择路线", CreateComponentMethod);
        }

        private static void ClearDataFromScene()
        {
            SceneObjectsCollection allObjects = scene.GetATScene().GetObjects();
            foreach (ATObject obj in allObjects)
            {
                if (obj.IsValid && obj.ATObjectType != ATObjectType.ReferenceAttachment)
                {
                    obj.DeleteFromScene();
                }
            }
        }


        public static void ImportCCFWork()
        {
            string strExePath = ATEC.ATDataCoreNET.ConfigurationManager.GetVariable("_ROOTDIR");

            string strSchemaFolder = strExePath + "CCFWorks\\";
            string strCCFWorkFile = strSchemaFolder;
            strCCFWorkFile += "Ebim\\";
            strCCFWorkFile += "ProjectModelExample.01.00";
            strCCFWorkFile += ".db";
            if (string.IsNullOrEmpty(strCCFWorkFile))
                return;

            ATCCLManager manger = ATCCLManager.Manager;
            ICCFWork ccfwork;
            StatusInt status = manger.ImportDBCCFWork(out ccfwork, strCCFWorkFile, masterATProject, false, true);
            return;
        }

        /// <summary>
        /// 开始建模流程
        /// </summary>
        public static void CreateComponentMethod()
        {
            //2. 显示界面，输入建模信息
            InitComponentInfo();

            //3. 解析轮廓
            ParserComponentProfile();

            //4. 建模，附加属性
            isDoModel = AddToFile();
            if (!isDoModel)
            {
                return;
            }
            //5. 刷新左树栏
            TreeManager.Entity().CreateProjectTree();
            //6.模型在View中居中
            ViewManager.FitView();
        }

        /// <summary>
        /// 初始化建模数据
        /// </summary>
        public static void InitComponentInfo()
        {
            componentModel.component.startStation = 400; //m
            componentModel.component.endStation = 1800;   //m
        }

        /// <summary>
        /// 解析轮廓
        /// </summary>
        public static void ParserComponentProfile()
        {
            XPoint3d center = XPoint3d.Zero;
            double radius_Out = 900 * ConstDef.CM_To_Uor;
            XVector3d normal = XVector3d.UnitZ;
            XEllipse3d arc = XEllipse3d.FromCenterRadiusNormal(center, radius_Out, normal);
            CurveSet.BoundaryType arcBndryType = CurveSet.BoundaryType.Outer;
            CurveSet arcCurve_Out = CurveSet.Create(arcBndryType);
            arcCurve_Out.Add(BasicCurve.CreateArc(arc));


            double radius_In = 800 * ConstDef.CM_To_Uor;
            XEllipse3d arc_In = XEllipse3d.FromCenterRadiusNormal(center, radius_In, normal);
            CurveSet arcCurve_In = CurveSet.Create(arcBndryType);
            arcCurve_In.Add(BasicCurve.CreateArc(arc_In));

            componentModel.Curve = new CurveSet(CurveSet.BoundaryType.Open);
            componentModel.Curve.Add(arcCurve_Out);
            componentModel.Curve.Add(arcCurve_In);
        }

        /// <summary>
        /// 构造实体
        /// </summary>
        /// <returns></returns>
        public static List<ATObject> BuildSolid()
        {
            List<ATObject> vecObjs = new List<ATObject>();

            //对桩号进行采样
            StationRange m_StRg = new StationRange(componentModel.component.startStation, componentModel.component.endStation);
            List<double> vecPos = m_StRg.Samples(ConstDef.g_dLoftStep);

            List<SolidCoreEntity> solidOut = new List<SolidCoreEntity>();
            //建模的单端最大长度为200m
            for (int iStartNum = 0; ; iStartNum += ConstDef.LoftNum)
            {
                List<double> vPos = new List<double>();

                for (int iSize = iStartNum; iSize <= iStartNum + ConstDef.LoftNum && iSize < vecPos.Count(); iSize++)
                {
                    vPos.Add(vecPos[iSize]);
                }

                //构造一组截面
                List<CurveSet> listCurve_Outter = new List<CurveSet>();
                List<CurveSet> listCurve_Inner = new List<CurveSet>();
                foreach (double d in vPos)
                {
                    //计算每个桩号处的轮廓变换矩阵
                    XTransform3d trsfm = AlignmentUtilMethod.CalcTransformForProfile(d); //d的单位是m
                    CurveSet pProfile = componentModel.Curve.Clone();
                    pProfile.TransformInPlace(trsfm);
                    {
                        CurveSet pOutter = pProfile.First().GetChildCurveSet().Clone();
                        CurveSet pInner = pProfile.Last().GetChildCurveSet().Clone();

                        listCurve_Outter.Add(pOutter);
                        listCurve_Inner.Add(pInner);
                    }
                }
                //outer
                SolidCoreEntity pBody_Outer = null;
                EntityUtl.Create.EntityFromLoft(out pBody_Outer, listCurve_Outter, null, scene, false, false);
                if (pBody_Outer == null)
                {
                    string errorStr = "外轮廓造体失败  ";
                    SSDPNET.ATDlgFuncs.DialogDmsgsPrint(errorStr);
                    return vecObjs;
                }

                //inner
                SolidCoreEntity pBody_Inner = null;
                EntityUtl.Create.EntityFromLoft(out pBody_Inner, listCurve_Inner, null, scene, false, false);
                if (pBody_Inner == null)
                {
                    string errorStr = "内轮廓造体失败  ";
                    SSDPNET.ATDlgFuncs.DialogDmsgsPrint(errorStr);
                    return vecObjs;
                }

                //扣减
                List<SolidCoreEntity> tools = new List<SolidCoreEntity> { pBody_Inner };
                ATECStatus status = EntityUtl.Modify.BooleanSubtract(out pBody_Outer, out tools);
                if (status == ATECStatus.Success && pBody_Outer != null)
                {
                    solidOut.Add(pBody_Outer);
                }
                else
                {
                    string errorStr = "扣减失败  ";
                    SSDPNET.ATDlgFuncs.DialogDmsgsPrint(errorStr);
                    return vecObjs;
                }

                //循环退出条件为：该段最后一个采样桩号 == 整段终点桩号
                if (vPos[vPos.Count() - 1] == vecPos[vecPos.Count() - 1])
                {
                    break;
                }
            }

            foreach (var body in solidOut)
            {
                // 绘制到屏幕
                ATObject obj = GeometryToATObject.ToObject(scene.GetATScene(), body, null);
                if (obj.IsValid)
                {
                    obj.AddToScene(); // 添加到 Scene
                    componentModel.id.Add(obj.ObjectId);
                    vecObjs.Add(obj);
                }
            }

            //创建一个命名组
            NamedGroup pGroup;
            StatusInt statusGroup = CreateNamedGroup(out pGroup);
            if (statusGroup != StatusInt.Success || pGroup == null)
            {
                return vecObjs;
            }
            NamedGroupStatus groupStatus;
            NamedGroupMemberFlags namedGroupMemberFlags = new NamedGroupMemberFlags();
            namedGroupMemberFlags.ForwardPropagate = 0;
            namedGroupMemberFlags.BackwardPropagate = 0;
            namedGroupMemberFlags.GroupPropagate = 0;

            //将多个体添加到一个组实现选中一个体同时高亮
            foreach (var obj in vecObjs)
            {
                ObjectId id = obj.ObjectId;
                groupStatus = pGroup.AddMember(id, obj.ATSceneRef, namedGroupMemberFlags);
            }
            groupStatus = pGroup.WriteToFile(true);

            return vecObjs;
        }

        /// <summary>
        /// 建模，并给ATObject附加属性
        /// </summary>
        /// <returns></returns>
        public static bool AddToFile()
        {
            //4. 建模
            List<ATObject> vecObjs = BuildSolid();

            // 属性值绑定到ATObject
            bool isSuccess = false;
            foreach (var obj in vecObjs)
            {
                if (obj != null)
                {
                    isSuccess = SSDPObject.EasyCCF.ToCCF(componentModel, obj);
                }
            }
            return isSuccess;
        }

        /// <summary>
        /// 创建命名组
        /// </summary>
        /// <param name="nameGroup"></param>
        /// <returns></returns>
        public static StatusInt CreateNamedGroup(out NamedGroup nameGroup)
        {
            NamedGroupCollection pNGCollection = new NamedGroupCollection(scene);
            if (pNGCollection == null)
            {
                nameGroup = new NamedGroup("", "", null, scene);
                return StatusInt.Error;
            }

            //先把当前场景中已经存在的命名组找出来，如果其中的成员数为0，就删掉
            foreach (var ng in pNGCollection)
            {
                //namedgroup中可以加图形元素，也可以加入group
                uint graphicMembers, groupMembers;
                ng.GetMemberCount(out graphicMembers, out groupMembers);
                if (graphicMembers == 0 && groupMembers == 0)
                {
                    ng.DeleteFromFile();
                }
            }

            string baseName = "ProjectExample";
            string groupName = pNGCollection.GetUniqueNameFromBase(baseName);

            NamedGroupFlags ngFlags = new NamedGroupFlags();
            ngFlags.AllowDuplicates = false;
            ngFlags.ExclusiveMembers = true;
            ngFlags.AllowFarReferences = false;
            ngFlags.Closed = false;
            ngFlags.SelectMembers = true;//选中一个体，整组高亮
            ngFlags.Anonymous = true;

            string description = "ProjectExampleSolid";
            nameGroup = new NamedGroup(groupName, description, ngFlags, scene);
            if (nameGroup == null)
            {
                return StatusInt.Error;
            }

            NamedGroupStatus groupStatus = nameGroup.WriteToFile(true);

            if (groupStatus != NamedGroupStatus.Success)
            {
                return StatusInt.Error;
            }
            return StatusInt.Success;
        }

    }
}
